package com.ruan.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruan.common.Code;
import com.ruan.common.Result;
import com.ruan.mapper.BusinessTripMapper;
import com.ruan.mapper.EmployeeMapper;
import com.ruan.pojo.*;
import com.ruan.pojoExt.BusinessTripExt;
import com.ruan.service.*;

import com.ruan.utils.DateUtils;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@CrossOrigin
@RequestMapping("/businessTrip")
public class BusinessTripController {

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private EmployeeService employeeService;

    @Resource
    private BusinessTripService businessTripService;

    @Autowired
    private DepartmentService departmentService;

    @Autowired
    private BusinessTripMapper businessTripMapper;

    @Resource
    private TripTypeService tripTypeService;

    @Autowired
    PositionService positionService;


    /**
     * 分页和条件查询全部在职员工的出差信息
     * @param currentPage 当前页
     * @param pageSize 每页最大数
     * @param LTOQueryCondition 查询条件：封装了月份和手机号字段
     * @return
     *///IPage<BusinessTrip>
    @PostMapping("/selectByPageAndCondition/{currentPage}/{pageSize}")
    @ApiOperation(value = "员工出差分页查询接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "currentPage", value = "页码", required = true, paramType = "path", dataType = "int"),
            @ApiImplicitParam(name = "pageSize", value = "每页记录数", required = true, paramType = "path", dataType = "int"),
            @ApiImplicitParam(name = "LTOQueryCondition", value = "出差信息查询条件", required = false, paramType = "body", dataType = "LTOQueryCondition")
    })
    //需要确保 LTOQueryCondition 不为 null，否则在生成键时会导致 NullPointerException。
    // 可以使用 #LTOQueryCondition?.name 和其他属性来避免这种情况。
//    @Cacheable(cacheNames = "businessTripCache",
//            key = "#currentPage + '-' " +
//                    "+ #pageSize " + "+ '-' " +
//                    "+ #LTOQueryCondition",
//            unless = "#result == null")//缓存某些空结果
    public Result selectByPageAndCondition(@PathVariable int currentPage,
                                           @PathVariable int pageSize,
                                           @RequestBody LTOQueryCondition LTOQueryCondition) {
//        System.out.println("selectByPageAndCondition的参数是："+pageSize+pageSize+LTOQueryCondition);
        Date month = LTOQueryCondition.getMonth();//2023-2-1
        Page<BusinessTrip> iPage=new Page<>(currentPage,pageSize);
//        LambdaQueryWrapper<BusinessTrip> queryWrapper = new LambdaQueryWrapper<>();
        QueryWrapper<BusinessTrip> queryWrapper = new QueryWrapper<>();
        //-----------------------------------------
        LambdaQueryWrapper<Employee> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.like(Employee::getName, LTOQueryCondition.getName());
        List<Employee> employeeList = employeeMapper.selectList(queryWrapper1);

        List<Long> employeeIds = employeeList.stream().map(Employee::getId).collect(Collectors.toList());
        queryWrapper.in("employee_id", employeeIds);//是QueryWrapper的技术语句
//        queryWrapper.in(Resign::getEmployeeId, employeeIds);
//        queryWrapper.like(LTOQueryCondition.getName()!=null,"name", LTOQueryCondition.getName());
        queryWrapper.eq(LTOQueryCondition.getDepartmentId()!=null,"department_id", LTOQueryCondition.getDepartmentId());
        queryWrapper.like("status","同意");

        queryWrapper.select("*","COUNT(employee_id) AS count").groupBy("employee_id");

        if (month!=null){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-01");
            String firstDay = sdf.format(month);//每月的第一天
            String lastDay = DateUtils.getLastDay(firstDay);//每月最后一天

//            queryWrapper.between(BusinessTrip::getLeaveTime,firstDay,lastDay);
            queryWrapper.between("leave_time",firstDay,lastDay);

            Page<BusinessTripExt> iPageExt=new Page<>();//封装
            businessTripService.page(iPage,queryWrapper);//page方法已经已经继承了IService,已经提供了分页查询方法，只需要把Page对象和queryWrapper对象构造好，传给他，自己就会进行分页查询

            BeanUtils.copyProperties(iPage,iPageExt,"records");//从iPage一个一个拷贝属性到iPageExt上(除了records)
            List<BusinessTrip> records = iPage.getRecords();
            List<BusinessTripExt> list = records.stream().map((item) -> {//item:遍历出来的每一个项目对象
                BusinessTripExt businessTripExt = new BusinessTripExt();//只有EmployeeExt符合项目管理页面的要求，所以new一个出来,进行填充
                BeanUtils.copyProperties(item,businessTripExt);//先填充入employee的普通属性
                Long departmentId = item.getDepartmentId();//拿到了每个员工所对应的部门id
                Long employeeId = item.getEmployeeId();


                Employee employee = employeeService.getById(employeeId);
                Department department = departmentService.getById(departmentId);

                if(employee != null){//能查到员工
                    businessTripExt.setEmployeeName(employee.getName());//填充入employee没有的employeeName属性
                    businessTripExt.setPhone(employee.getPhone());
                }
                Position position = positionService.getById(employee.getPositionId());
                if(position != null) {//能查到员工的部门
                    businessTripExt.setPosition(position.getPname());
                }
                if(department != null){//能查到员工的部门
                    String departmentName = department.getName();
                    businessTripExt.setDepartmentName(departmentName);//填充入employee没有的employeeName属性
                }
                return businessTripExt;//填充完新键的employeeExt之后，返回，把遍历的这些employeeExt对象搜集起来后
            }).collect(Collectors.toList());//就转成集合了，赋给List<EmployeeExt> list


//            System.out.println("BusinessTriplist1里有了什么"+list);//.toString()
            iPageExt.setRecords(list);//list获得了改造过后的departmentExt集合之后，被用来设置page对象的Records属性
            return new Result(Code.SELECT_OK,iPageExt);
//            return businessTripMapper.selectPage(iPage,queryWrapper);
        }else {

            Page<BusinessTripExt> iPageExt=new Page<>();//封装
            businessTripService.page(iPage,queryWrapper);//page方法已经已经继承了IService,已经提供了分页查询方法，只需要把Page对象和queryWrapper对象构造好，传给他，自己就会进行分页查询

            BeanUtils.copyProperties(iPage,iPageExt,"records");//从iPage一个一个拷贝属性到iPageExt上(除了records)
            List<BusinessTrip> records = iPage.getRecords();
            List<BusinessTripExt> list = records.stream().map((item) -> {//item:遍历出来的每一个项目对象
                BusinessTripExt businessTripExt = new BusinessTripExt();//只有EmployeeExt符合项目管理页面的要求，所以new一个出来,进行填充
                BeanUtils.copyProperties(item,businessTripExt);//先填充入employee的普通属性
                Long departmentId = item.getDepartmentId();//拿到了每个员工所对应的部门id
                Long employeeId = item.getEmployeeId();


                Employee employee = employeeService.getById(employeeId);
                Department department = departmentService.getById(departmentId);

                if(employee != null){//能查到员工
                    businessTripExt.setEmployeeName(employee.getName());//填充入employee没有的employeeName属性
                    businessTripExt.setPhone(employee.getPhone());

                }
                Position position = positionService.getById(employee.getPositionId());
                if(position != null) {//能查到员工的部门
                    businessTripExt.setPosition(position.getPname());
                }
                if(department != null){//能查到员工的部门
                    String departmentName = department.getName();
                    businessTripExt.setDepartmentName(departmentName);//填充入employee没有的employeeName属性
                }
                return businessTripExt;//填充完新键的employeeExt之后，返回，把遍历的这些employeeExt对象搜集起来后
            }).collect(Collectors.toList());//就转成集合了，赋给List<EmployeeExt> list
//            System.out.println("BusinessTriplist2里有了什么"+list);//.toString()
            iPageExt.setRecords(list);//list获得了改造过后的departmentExt集合之后，被用来设置page对象的Records属性
            return new Result(Code.SELECT_OK,iPageExt);
//            return businessTripMapper.selectPage(iPage,queryWrapper);
        }
    }

    @GetMapping("/getTripType")
    public Result getTripType(){
        List<TripType> tripTypeList = null;
        try {
            tripTypeList = tripTypeService.getTripType();
            return new Result(Code.SELECT_OK,tripTypeList);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.SELECT_ERR,"请假事由列表查询失败！");
        }

    }

    @PutMapping("/stopType/{id}")
    public Result stopType(@PathVariable Integer id){
        try {
            tripTypeService.stopType(id);
            return new Result(Code.UPDATE_OK,"禁用成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.UPDATE_ERR,"禁用失败！");
        }
    }

    @PutMapping("/startType/{id}")
    public Result startType(@PathVariable Integer id){
        try {
            tripTypeService.startType(id);
            return new Result(Code.UPDATE_OK,"启用成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.UPDATE_ERR,"启用失败！");
        }
    }

    @PostMapping("/getTripDetail")
    public Result getTripDetail(@RequestBody LTODetailCondition LtoDetailCondition){
        List<BusinessTripExt> businessTripList = businessTripService.selectLeaveDetailByPhoneAndDate(LtoDetailCondition);

        if (businessTripList!=null){
            return new Result(Code.SELECT_OK,businessTripList);
        }
        return new Result(Code.SELECT_ERR,"查询详细请假信息失败！");
    }


    /**
     * 获得待审核出差列表
     * @return
     */
    @GetMapping("/getAudit")
    public Result getAudit() {
        LambdaQueryWrapper<BusinessTrip> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BusinessTrip::getStatus,"待审核");
        List<BusinessTrip> businessTrips = businessTripMapper.selectList(queryWrapper);


        List<BusinessTripExt> businessTripExtList = new ArrayList<>();
        for(BusinessTrip businessTrip : businessTrips){
            BusinessTripExt businessTripExt = new BusinessTripExt();

            //属性迁移
            BeanUtils.copyProperties(businessTrip, businessTripExt);
//            System.out.println("属性迁移完了吗1："+businessTripExt);
            //查的是多人的待审核出差列表，所以名字要各自获得/\/\/\
            LambdaQueryWrapper<Employee> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(Employee::getId,businessTrip.getEmployeeId());
            Employee employee = employeeMapper.selectOne(queryWrapper1);
            businessTripExt.setEmployeeName(employee.getName());
            Position position = positionService.getById(employee.getPositionId());
            if(position != null) {
                businessTripExt.setPosition(position.getPname());
            }
            businessTripExt.setPhone(employee.getPhone());
            Department department = departmentService.getById(employee.getDepartmentId());
            businessTripExt.setDepartmentName(department.getName());
            businessTripExtList.add(businessTripExt);
//            System.out.println("businessTripExtList是："+businessTripExtList);
        }
        return new Result(Code.SAVE_OK,businessTripExtList);
//        return BusinessTripExt;
    }


    @PutMapping("/agreed/{id}/{adminId}")
    public Result agreed(@PathVariable Integer id, @PathVariable Integer adminId){
        try {
            businessTripService.agreed(id,adminId);
            return new Result(Code.UPDATE_OK,"审核成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.UPDATE_ERR,"审核失败，请检查系统！");
        }

    }

    @PutMapping("/refuse/{id}/{adminId}")
    public Result refuse(@PathVariable Integer id, @PathVariable Integer adminId){
        try {
            businessTripService.refuse(id,adminId);
            return new Result(Code.UPDATE_OK,"审核成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.UPDATE_ERR,"审核失败，请检查系统！");
        }
    }

    @GetMapping("/getUsingTripType")
    public Result getUsingTripType(){
        try {
            List<TripType> tripTypeList = tripTypeService.getUsingTripType();
            return new Result(Code.SELECT_OK,tripTypeList);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.SELECT_OK,"查询可用出差方式失败！");
        }
    }

    @PostMapping("/appForTrip")
    public Result appForTrip( @RequestBody BusinessTrip businessTrip){
//        System.out.println("出差申请传的参数："+businessTrip);
        return  businessTripService.appForTrip(businessTrip);
    }

    @PostMapping("/getSelfTrip/{currentPage}/{pageSize}")
    public Result getSelfTrip(@PathVariable int currentPage,
                              @PathVariable int pageSize,
                              @RequestBody QuerySelfAttendanceCondition querySelfAttendanceCondition){


        System.out.println("phone是"+ querySelfAttendanceCondition.getPhone());

        IPage<BusinessTrip> iPage = businessTripService.getSelfTrip(currentPage,pageSize, querySelfAttendanceCondition);

        if (iPage!=null){
            return new Result(Code.SELECT_OK,iPage);
        }
        return new Result(Code.SELECT_ERR,"查询个人详细出差信息失败！");
    }

    @DeleteMapping("/cancelTrip/{id}")
    public Result cancelTrip(@PathVariable Integer id){
        try {
            businessTripService.cancelTrip(id);
            return new Result(Code.DELETE_OK,"撤销出差申请成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.DELETE_ERR,"撤销出差申请失败！");
        }
    }

    //上报实际花费
    @PutMapping("/setActualCost/{id}/{actualCost}")
    public Result setActualCost(@PathVariable Integer id,
                                @PathVariable BigDecimal actualCost){

        try {
            businessTripService.setActualCost(id,actualCost);
            return new Result(Code.UPDATE_OK,"上报实际花费成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.UPDATE_ERR,"上报实际花费失败！");
        }
    }

    @GetMapping("/getActualCost/{id}")
    public Result getActualCost(@PathVariable Integer id){

        return businessTripService.getActualCost(id);

    }

    @PostMapping("/addTrip/{adminId}")
    public Result addBusinessTrip(@PathVariable Integer adminId, @RequestBody BusinessTrip businessTrip){
        try {
            businessTripService.addBusinessTrip(adminId,businessTrip);
            return new Result(Code.SAVE_OK,"候补出差记录成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.SAVE_ERR,"候补出差记录失败！");
        }
    }
}
